//
// Created by nilyang on 2022/8/9.
//
#include <fstream>
#include <iostream>
#include <re2/re2.h>
#include <sstream>
#include <string>
#include "regex_re2.h"

namespace nilyang {

    using namespace re2;

    /// 该函数才能把整个文件数据读出完
    std::string get_file_contents(const char *filename) {
        std::ifstream infile(filename, std::ios::in | std::ios::binary);
        if (infile.is_open()) {
            std::ostringstream contents;
            contents << infile.rdbuf();
            infile.close();
            return (contents.str());
        }

        return std::string{""};
    }

    /// Google RE2 正则测试
    int re2_exec_by_text(int argc, char *argv[]) {
        std::cout << "--------- RE2 Regex ----------" << std::endl;

        std::string regStr, dataStr;
        std::string regFile, dataFile;

        if (argc >= 3) {
            regFile = argv[1];
            dataFile = argv[2];
            std::cout << "正则文件= " << regFile << std::endl;
            std::cout << "文本文件= " << dataFile << std::endl;
        } else {
            regFile = "./reg.txt";
            dataFile = "./data.txt";
        }

        // read from file
        regStr = get_file_contents(static_cast<const char *>(regFile.c_str()));
        std::cout << "正则表达式: " << regStr << std::endl;
        dataStr = get_file_contents(static_cast<const char *>(dataFile.c_str()));
        std::cout << "待测试字符串: " << dataStr << std::endl;

        if (regStr.empty()) {
            std::cout << "正则表达式文件为空 \n";
            return -1;
        }
        if (dataStr.empty()) {
            std::cout << "待测试字符串文件为空 \n";
            return -1;
        }


        /// RE2 正则
        RE2 r(regStr);

        const StringPiece input(dataStr);
        StringPiece group[4];

        // bool isOk = RE2::FindAndConsume(&input, r, &arg1, &arg2, &arg3, &arg4);
        bool isOk = r.Match(input, 0, input.size(), RE2::UNANCHORED, group, 4);
        std::cout << "匹配结果：" << (isOk ? "匹配成功" : "匹配失败")
                  << "\n分组信息："
                  << "\ngroup[0] = " << group[0]
                  << "\ngroup[1] = " << group[1]
                  << "\ngroup[2] = " << group[2]
                  << "\ngroup[3] = " << group[3]
                  << "\n";


        return 0;
    }

}